Date : 6 d�cembre 1991
Protection : MOT DE PASSE
Programme : MIGHT and MAGIC III
Outils : SOFT-ICE V2.50
Fichier : MM3.EXE
Temps pass� : 3 heures
Soci�t� : NEW WORLD COMPUTING
Divers : Confection d'un lanceur COM.
Origine : B.Y.
Num�ro : 154
Un examen du fichier EXE avant toute chose me montre qu'il est compact�
par une m�thode non publique. Avant m�me de trouver la protection cela
indique qu'il faudra utiliser un lanceur pour d�jouer la demande du
mot de passe. Mais avant toute chose il faut d'abord trouver la
protection. Je nage pendant un bout de temps avant de me d�cider �
utiliser la solution ultime qui consiste � comparer un programme se
d�roulant en ayant tap� un code correct avec un programme dans lequel
j'ai juste appuy� sur la touche ENTER.
Les deux programmes se d�roulent de la m�me fa�on jusqu'� un CALL 153
duquel on revient par un RETF ! Et la position du retour SS:SP est
bien entendu diff�rente suivant que l'on a tap� le bon ou le mauvais
code. Smart isn'it ?.
J'ex�cute ce CALL au pas � pas au moins une demi-douzaine de fois avant
de comprendre de quelle mani�re je me retrouve avec des vecteurs de
retour diff�rent dans un cas et dans l'autre. Cette routine est bien
celle qui teste les caract�res tap�s lors de la demande du code.
Elle est appel�e en 9CCA:0008 par un CALL 0153 et appara�t ci-dessous
compl�te:
SUB AX,AX
SUB SI,+0D
AND BX,EFDF
MOV DS,DX
MOV DX,7F60
MOV CL,20
0163: LODSB <�ͻ ; Cha�ne des caract�res tap�s DS:SI
AND AL,DH �
����������� JZ 01A8 � ; Si z�ro ( fin de cha�ne ) 01A8
� CMP AL,CL �
����������� JZ 01A8 �
� CMP AL,DL �
� JB 0172 ͻ �
� SUB AL,CL � �
� 0172: ROR BL,1 <ͼ �
� XCHG BL,BH �
� ROR BX,1 �
� ADD BX,AX �
� JMP 0163 �ͼ
� ��> 017C: POP BX
� � POP SI
� � POP DS
� � 017F: INC SI <������������ͻ
� � 0180: CMP WORD PTR [SI],5374 � <�ͻ
� � JNZ 017F �������������ͼ �
� � INC SI �
� � INC SI �
� � CMP WORD PTR [SI],6570 �
� � JNZ 0180 ������������������ͼ
� � INC SI
� � INC SI
� � PUSH DS
� � MOV CX,0027
� � 0194: XOR [SI],CL <�ͻ
� � INC SI �
� � LOOP 0194 ����ͼ
� � ADD DI,0403
� � XOR DX,08E2
� � PUSH DI
� � PUSH BX
� � MOV CX,F001
� � JNZ 01B5 ����ͻ
�����>01A8: MOV SI,001E �
� POP AX �
� POP CX �
� POP DS �
� 01AE: LODSW <�ͻ �
� CMP AX,BX � �
����01B1: JZ 017C � � ; adr_IP = 01B1, � modifier par JMP.
LOOP 01AE �ͼ �
01B5: ADD CX,0FFF <�ͼ
POP DS
RETF
Lorsque l'on tape juste ENTER le programme saute directement en 1A8
puis boucle dans LOOP 1AE. Dans ce dernier cas il ne trouve jamais
d'�galit� et lorsque CX = 0 il sort par le RETF avec des valeurs de
SS:SP ne correspondant pas � la suite normale du programme:
1473:058C apr�s l'ex�cution du RETF.
Dans le cas d'une bonne r�ponse il passe par 017C et en examinant la
suite du code on s'aper�oit que l'on fait deux PUSH DI et DX avant de
faire un RETF. DI doit contenir 058C pour que tout se passe bien.
D�s lors il ne suffit plus que de modifier le test en 01B1 en saut
inconditionnel. Et voil�.
Ci dessous le listing.asm qui comporte deux nouveaut�s:
1) Toutes les r�f�rences au programme fils ainsi que la fen�tre
d'affichage de FREDDY_SOFT sont XOR� par un XOR variable appliqu� sur
une zone d�limit�e par des A5A5. Cette zone pouvant �tre
indiff�rement du code ou des donn�es.
La fen�tre n'est affich�e que si une carte VGA est d�tect�e. En EGA
la protection est enlev�e mais aucun message n'apparait.
2) Une autre "am�lioration" consiste � remettre en place imm�diatement
apr�s l'action du patch, le vecteur d'origine de l'interruption
d�tourn�e. Impossible d'utiliser la fonction 25h de l'INT21h puisque le
DOS n'est pas r�entrant. Cela aurait fonctionn� pour les autres
interruptions mais pas la 21h.
; PATCH POUR LE PROGRAMME MIGHT and MAGIC III
; DETOURNEMENT DE L'INT 21 SOUS-FONCTION 42
;
;******************************************************************************
; ZONE A INITIALISER
adr_ip1 equ 01b1h ; adresse dont le contenu est � modifier.
anc_val equ 0c974h ; Valeur d'origine � rechercher.
nouv_val equ 0c9ebh ; Nouvelle valeur.
INT_DET equ 21h ; Le num�ro de l'INT que l'on veut utiliser.
sous_fonction equ 42h ; Sous-fonction utilis�e.
;******************************************************************************
seg_a segment byte public
assume cs:seg_a, ds:seg_a, es:seg_a, ss:seg_a
org 100h
sto proc far
start:
jmp init ; r�duire la m�moire et d�placer la
db 90h ; pile plus pr�s.
paramet dw 0 ; M�me bloc d'environnement.
ENVIR dw 0 ; Les param�tres de la ligne de
data_3 dw 0 ; commande sont recopi�s ici puis
FCB_1 dw 0 ; transmis au programme fils. ( 80h )
data_5 dw 0
FCB_2 dw 0
data_7 dw 0
sauve_SP dw 0
sauve_SS dw 0
data_9 dw 0, 0
drap equ 0
;------------------------------ PROGRAMME PERE ------------------------------
loc_1: mov sauve_SP,sp
mov sauve_SS,ss
mov ax,80h
mov ENVIR,ax ; Ligne de commande...
mov data_3,ds
mov ax,5Ch ; Premier FCB ( inutilis� )
mov FCB_1,ax
mov data_5,ds
mov ax,6Ch ; Second FCB ( inutilis� )
mov FCB_2,ax
mov data_7,ds
mov ah,35h
mov al,INT_DET
int 21h ; DOS Services ah=function 35h
; get intrpt vector al in es:bx
mov cs:data_9,bx
mov word ptr cs:data_9+2,es
mov ah,25h
mov al,INT_DET
lea dx,cs:[_int] ; Load effective addr
int 21h ; DOS Services ah=function 25h
; set intrpt vector al to ds:dx
lea dx,cs:[nom_prg] ; Load effective addr
push ds
pop es
lea bx,cs:[paramet] ; Load effective addr
mov al,0
mov ah,4Bh
int 21h ; Appel du programme fils.
; run progm @ds:dx, parm @es:bx
mov sp,sauve_SP
mov ss,sauve_SS
cmp al,2 ; teste le code de retour du programme
jnz ok ; fils, 02 si pas trouv�.
mov dx,offset mess_err
mov ah,9
int 21h
; Les cinq instructions suivantes sont facultatives puisque le
; vecteur d'origine est remis en place d�s que le patch est effectu�.
; Le seul but est d'�viter le plantage du PC dans l'hypoth�se o� l'on
; lance le programme p�re et que celui-ci ne trouve pas le programme
; fils. A ce moment l� on remet tout en place et on quitte.
ok: mov ah,25h
mov al,INT_DET
mov dx,cs:data_9
mov ds,word ptr cs:data_9+2
int 21h
mov ah,4Ch
int 21h ; terminate with al=return code
sto endp
;---------------------------- int d�tourn�e --------------------------------
int_entry proc far
_int: push ax
push ds
push bx
pushf ; Push flags
cmp ah,sous_fonction ; Sous - fonction de l'INT.
jne loc_2 ; Jump if not equal
mov ax,sp
add sp,+34
pop ds
cmp word ptr ds:[adr_ip1],anc_val ; Si ok on patche.
jnz s
mov word ptr ds:[adr_ip1],nouv_val ; On y place le patch.
xor bx,bx
mov ds,bx
; L'INT 21 n'est pas r�entrante, on ne peut donc pas se servir de
; la fonction 25h ( set int. vector )
mov bx,word ptr cs:data_9 ; Je remets manuellement
mov ds:[INT_DET*4],bx ; en place le vecteur
mov bx,word ptr cs:data_9+2 ; de l'INT d�tourn�e.
mov ds:[INT_DET*4+2],bx
s: mov sp,ax
loc_2: popf
pop bx
pop ds
pop ax
jmp dword ptr cs:data_9
int_entry endp
;------------ REDUCTION DE LA PLACE OCCUPEE PAR LE PROGRAMME COM ------------
init: ; D�codage du texte.
cld ; Pour incr�menter SI et DI.
xor ax,ax
mov si,offset chaine ; pointe sur le d�but de la chaine.
mov di,si ; DI �galement.
mov cx,offset chaine_fin - offset chaine
; 28 lignes de 6 caract�res sont XOR�s.
; + mess_err ( 30 ) + nom_prog ( 13 ).
toto: lodsb ; On cherche...
xor al,ah ; On XOR.
stosb ; On remet.
xchg ah,al
loop toto ; Et on tourne tant que CX # 0.
mov ax,1a00h ; Test si carte + moniteur VGA
int 10h
cmp al,1ah
je graf ; Si oui on affiche la fen�tre FREDDY_SOFT.
suite1: mov ah,4ah
mov bx,offset fin ; Fin du programme en BX.
mov cl,4 ; Divis� par 4 pour avoir des paragraphes.
shr bx,cl
inc bx ; On en rajoute un par s�curit�.
int 21h ; Execution de la fonction 4Ah.
mov sp,offset fin ; on d�place la pile en "fin" car elle est
jmp loc_1 ; plac�e en FFFE dans un programme COM.
graf: xor ah,ah ; Raz de l'�cran
mov al,3
int 10h
mov ax,1301h ; Mode 01 attribut couleur dans BL.
mov bx,004bh ; Page 0.
mov cx,28 ; nombre de char.
mov dx,0a19h ; ligne,colonne.
lea bp,cs:[chaine]
ligne_suiv: int 10h
inc dh
add bp,28
cmp dh,10h ; 6 lignes de 28 caract�res.
jb ligne_suiv
mov ah,2 ; Pour faire disparaitre le curseur.
xor bh,bh ; Page ecran 0.
mov dh,25
int 10h
jmp suite1
db 55h,0aah ; Identificateur de d�but.
chaine: db '��������FREDDY_SOFT!������Ŀ'
db '� �'
db '� MIGHT & MAGIC ]I[ Bypass �'
db "� I hope you'll enjoy it �"
db '� �'
db '�����������ETOYOC�����������'
mess_err db 0ah,0dh,'Programme enfant non trouv�','$'
nom_prg db 'mm3.exe',0,0,0,0,0,0 ; 12 car max + nul
chaine_fin: db 0aah,55h ; Identificateur de fin.
fin_init label near
;----------------------- PLACE RESERVEE POUR LA PILE ------------------------
dw 100 dup (' ')
fin equ this byte ; ici le sommet de la pile, SP.
seg_a ends
end start
FREDDY
|